package com.digitaldreamers.spaceshooter.gameobject;

import org.andengine.engine.handler.IUpdateHandler;
import org.andengine.entity.Entity;
import org.andengine.entity.IEntity;
import org.andengine.entity.modifier.ScaleModifier;
import org.andengine.entity.particle.BatchedSpriteParticleSystem;
import org.andengine.entity.particle.emitter.PointParticleEmitter;
import org.andengine.entity.particle.initializer.BlendFunctionParticleInitializer;
import org.andengine.entity.particle.initializer.ExpireParticleInitializer;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.sprite.UncoloredSprite;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.util.modifier.IModifier;
import org.andengine.util.modifier.IModifier.IModifierListener;

import android.opengl.GLES20;

import com.digitaldreamers.spaceshooter.Constants;
import com.digitaldreamers.spaceshooter.scene.GameScene;

public class LaserBeam extends Entity {
	private GameScene mGameScene;
	private Sprite mLaserBeamSprite;
	
	private BatchedSpriteParticleSystem mParticleSystem;
	private PointParticleEmitter mEmitter;
	private ITextureRegion mParticlePointTextureRegion;
	
	private float mSecondsElapsed;
	private boolean mState1Done;
	private boolean mState2Done;
	private boolean mState3Done;
	
	public LaserBeam(GameScene gameScene, ITextureRegion particlePointTextureRegion, Sprite laserBeamSprite) {
		this.mGameScene = gameScene;
		this.mParticlePointTextureRegion = particlePointTextureRegion;
		this.mLaserBeamSprite = laserBeamSprite;
		this.setAnchorCenterY(0f);
		
		this.mState1Done = false;
		this.mState2Done = false;
		this.mState3Done = false;
	}
	
	@Override
	public void onAttached() {
		this.mSecondsElapsed = 0f;
		this.registerUpdateHandler(new IUpdateHandler() {
			@Override
			public void onUpdate(float pSecondsElapsed) {
				LaserBeam.this.mSecondsElapsed += pSecondsElapsed;
				if(!LaserBeam.this.mState1Done) {
					LaserBeam.this.state1();
					return;
				}
				
				if(LaserBeam.this.mSecondsElapsed >= Constants.LASER_BEAM__STATE_1_LIFE_TIME_END && !LaserBeam.this.mState2Done) {
					LaserBeam.this.state2();
					return;
				}
				
				if(LaserBeam.this.mSecondsElapsed >= Constants.LASER_BEAM__STATE_2_LIFE_TIME_END && !LaserBeam.this.mState3Done) {
					LaserBeam.this.state3();
					return;
				}
			}
			
			@Override
			public void reset() {
				
			}
		});
	}
	
	private void state1() {
		this.setSize(this.mParticlePointTextureRegion.getWidth(), this.mParticlePointTextureRegion.getHeight());
		this.mEmitter = new PointParticleEmitter((this.getWidth() - this.mParticlePointTextureRegion.getWidth()) / 2f, 0f);
		this.mParticleSystem = new BatchedSpriteParticleSystem(this.mEmitter, Constants.LASER_BEAM__RATE_MINIMUM, Constants.LASER_BEAM__RATE_MAXIMUM, Constants.LASER_BEAM__PARTICLES_MAXIMUM, this.mParticlePointTextureRegion, this.mGameScene.mVBOM);
		this.mParticleSystem.addParticleInitializer(new ExpireParticleInitializer<UncoloredSprite>(Constants.LASER_BEAM__STATE_1_LIFE_TIME_END));
		this.mParticleSystem.addParticleInitializer(new BlendFunctionParticleInitializer<UncoloredSprite>(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA));
		this.attachChild(this.mParticleSystem);
		this.mState1Done = true;
	}
	
	private void state2() {
		this.mGameScene.mEngine.runOnUpdateThread(new Runnable() {
			@Override
			public void run() {
				LaserBeam.this.mParticleSystem.detachSelf();
			}
		});
		
		this.setSize(this.mLaserBeamSprite.getWidth(), this.mLaserBeamSprite.getHeight());
		this.setScaleY(0f);
		this.mLaserBeamSprite.setPosition(this.getWidth() / 2f, 0f);
		this.mLaserBeamSprite.setAnchorCenterY(0f);
		this.attachChild(this.mLaserBeamSprite);
		
		ScaleModifier scaleModifier = new ScaleModifier(Constants.LASER_BEAM__STATE_2_SCALE_TIME, Constants.LASER_BEAM__STATE_2_FROM_SCALE_X, Constants.LASER_BEAM__STATE_2_TO_SCALE_X, Constants.LASER_BEAM__STATE_2_FROM_SCALE_Y, Constants.LASER_BEAM__STATE_2_TO_SCALE_Y);
		this.registerEntityModifier(scaleModifier);
		
		this.mState2Done = true;
	}
	
	private void state3() {
		ScaleModifier scaleModifier = new ScaleModifier(Constants.LASER_BEAM__STATE_3_SCALE_TIME, Constants.LASER_BEAM__STATE_3_FROM_SCALE_X, Constants.LASER_BEAM__STATE_3_TO_SCALE_X, Constants.LASER_BEAM__STATE_3_FROM_SCALE_Y, Constants.LASER_BEAM__STATE_3_TO_SCALE_Y);
		scaleModifier.addModifierListener(new IModifierListener<IEntity>() {
			@Override
			public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem) {
				
			}
			
			@Override
			public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem) {
				LaserBeam.this.mGameScene.mEngine.runOnUpdateThread(new Runnable() {
					@Override
					public void run() {
						LaserBeam.this.mLaserBeamSprite.detachSelf();
						LaserBeam.this.detachSelf();
					}
				});
			}
		});
		this.registerEntityModifier(scaleModifier);
		this.mState3Done = true;
	}
}
